package com.gd.data.platform.service.realtime;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.gd.data.platform.dto.RealtimeMonitorData;
import com.gd.data.platform.mapper.ApiCallLogMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 实时监控服务
 * 提供实时监控数据计算和缓存
 * 
 * @author gd-data-platform
 * @since 1.0.0
 */
@Slf4j
@Service
public class RealtimeMonitorService {

    @Autowired
    private ApiCallLogMapper apiCallLogMapper;

    // 暂时注释掉未使用的依赖，后续功能扩展时会使用
    // @Autowired
    // private DownloadLogMapper downloadLogMapper;

    // @Autowired
    // private RealtimeMetricsMapper realtimeMetricsMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String REALTIME_CACHE_KEY = "realtime:monitor:data";
    private static final int CACHE_EXPIRE_SECONDS = 10; // 10秒缓存过期

    /**
     * 获取实时监控数据
     */
    public RealtimeMonitorData getRealtimeMonitorData() {
        // 先从缓存获取
        RealtimeMonitorData cachedData = (RealtimeMonitorData) redisTemplate.opsForValue().get(REALTIME_CACHE_KEY);
        if (cachedData != null) {
            return cachedData;
        }

        // 计算时间窗口（最近1分钟）
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minus(1, ChronoUnit.MINUTES);

        RealtimeMonitorData data = new RealtimeMonitorData();

        try {
            // 计算总调用量
            Long totalCallCount = apiCallLogMapper.countCallsByTimeRange(startTime, endTime);
            data.setTotalCallCount(totalCallCount);

            // 计算成功调用量
            Long successCallCount = apiCallLogMapper.countSuccessCallsByTimeRange(startTime, endTime);
            data.setSuccessCallCount(successCallCount);

            // 计算失败调用量
            Long failureCallCount = apiCallLogMapper.countFailureCallsByTimeRange(startTime, endTime);
            data.setFailureCallCount(failureCallCount);

            // 计算失败率
            if (totalCallCount > 0) {
                double failureRate = (double) failureCallCount / totalCallCount;
                data.setFailureRate(failureRate);
            } else {
                data.setFailureRate(0.0);
            }

            // 计算平均响应时间
            Double avgResponseTime = apiCallLogMapper.getAvgResponseTime(startTime, endTime);
            data.setAvgResponseTime(avgResponseTime != null ? avgResponseTime : 0.0);

            // 获取接口调用排行
            List<Map<String, Object>> apiRankings = apiCallLogMapper.getApiCallRankings(startTime, endTime, 10);
            data.setApiCallRankings(convertToApiCallRankings(apiRankings));

            // 获取IP访问排行
            List<Map<String, Object>> ipRankings = apiCallLogMapper.getIpAccessRankings(startTime, endTime, 10);
            data.setIpAccessRankings(convertToIpAccessRankings(ipRankings));

            // 设置更新时间
            data.setUpdateTime(LocalDateTime.now());

            // 缓存数据
            redisTemplate.opsForValue().set(REALTIME_CACHE_KEY, data, CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);

            log.info("实时监控数据计算完成，总调用量：{}，失败率：{}", totalCallCount, data.getFailureRate());

        } catch (Exception e) {
            log.error("获取实时监控数据失败", e);
            throw new RuntimeException("获取实时监控数据失败", e);
        }

        return data;
    }

    /**
     * 检查告警条件
     */
    public void checkAlertConditions(RealtimeMonitorData data) {
        // 检查调用量告警
        if (data.getTotalCallCount() > 100) {
            log.warn("调用量告警：当前调用量 {} 超过阈值 100", data.getTotalCallCount());
        }

        // 检查失败率告警
        if (data.getFailureRate() > 0.05) {
            log.warn("失败率告警：当前失败率 {} 超过阈值 5%", data.getFailureRate() * 100);
        }

        // 检查IP下载次数告警（需要从下载日志中获取）
        // 这里需要实现IP下载次数检查逻辑
        // 由于需要按IP统计下载次数，暂时跳过具体实现
    }

    /**
     * 转换为API调用排行
     */
    private List<RealtimeMonitorData.ApiCallRanking> convertToApiCallRankings(List<Map<String, Object>> rankings) {
        return rankings.stream().map(ranking -> {
            RealtimeMonitorData.ApiCallRanking item = new RealtimeMonitorData.ApiCallRanking();
            item.setApiName((String) ranking.get("api_name"));
            item.setCallCount(((Number) ranking.get("call_count")).longValue());
            item.setSuccessRate(((Number) ranking.get("success_rate")).doubleValue());
            return item;
        }).collect(java.util.stream.Collectors.toList());
    }

    /**
     * 转换为IP访问排行
     */
    private List<RealtimeMonitorData.IpAccessRanking> convertToIpAccessRankings(List<Map<String, Object>> rankings) {
        return rankings.stream().map(ranking -> {
            RealtimeMonitorData.IpAccessRanking item = new RealtimeMonitorData.IpAccessRanking();
            item.setClientIp((String) ranking.get("client_ip"));
            item.setAccessCount(((Number) ranking.get("access_count")).longValue());
            return item;
        }).collect(java.util.stream.Collectors.toList());
    }
}
